package com.hifar.test.entrust.controller;

import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hifar.abi.flow.utils.FlowApiUtils;
import com.hifar.abi.flow.utils.FlowConst;
import com.hifar.abi.utils.minio.MinioUtils;
import com.hifar.common.QueryParamBean;
import com.hifar.constant.FlowCodeConsts;
import com.hifar.fw.json.JsonUtils;
import com.hifar.fw.utils.bean.BusiConst;
import com.hifar.fw.utils.bean.BusiRequest;
import com.hifar.fw.utils.lang.StringUtils;
import com.hifar.model.VO.ExportQueryParamsVO;
import com.hifar.model.VO.IdVO;
import com.hifar.model.VO.QueryParamsVO;
import com.hifar.plat.baseModal.pojo.BaseOssFiles;
import com.hifar.sys.*;
import com.hifar.test.debugApi.client.DebugApiClient;
import com.hifar.test.entrust.constant.EntrustConsts;
import com.hifar.test.entrust.pojo.HfEnvEntrust;
import com.hifar.test.entrust.pojo.VO.*;
import com.hifar.test.entrust.service.IHfEnvEntrustService;
import com.hifar.test.oaApi.client.OaTaskClient;
import com.hifar.test.report.pojo.HfEnvReport;
import com.hifar.test.report.service.IHfEnvReportService;
import com.hifar.test.task.service.IHfEnvTaskService;
import com.hifar.test.test.pojo.VO.HfEnvEntrustTaskVO;
import com.hifar.test.test.service.IHfEnvTestService;
import com.tssk.kylx.fw.utils.id.IdUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * <p>
 * 委托单 前端控制器 default
 * </p>
 *
 * @author wei
 * @since 2024-12-04 15:51:56
 */
@RestController
@RequestMapping("/api/busi/test/hfEnvEntrustController")
@Api(tags = "委托单功能")
public class HfEnvEntrustController {

    private static final Logger log = LoggerFactory.getLogger(HfEnvEntrustController.class);

    @Autowired
    private IHfEnvEntrustService hfEnvEntrustService;
    @Autowired
    private IHfEnvTestService testService;
    @Autowired
    private IHfEnvReportService reportService;
    @Autowired
    private IHfEnvTaskService taskService;


    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();


    @PostMapping(value = "/list")
    @ApiOperation(value = "委托单功能:分页查询列表")
    public BusiResponse list(@RequestBody @Validated QueryParamsVO queryParamsVO) {
        QueryParamBean<HfEnvEntrustVO> queryParamBean = new QueryParamBean<>(queryParamsVO);
        queryParamBean.addColumns(HfEnvEntrust.class, "e");
        QueryWrapper<HfEnvEntrustVO> queryWrapper = queryParamBean.getQueryWrapper();
        Page<HfEnvEntrustVO> page = queryParamBean.getPage();
        queryWrapper.in("e.secret_level", SystemLoginUser.dataSecretSet);
        queryWrapper.orderByDesc("e.create_time");
        Page<HfEnvEntrustVO> pageData = hfEnvEntrustService.pageVO(page, queryWrapper);
        /* 计算分页信息返回给前端 */
        PageResult pageResult = SystemUtil.parsePage(page, pageData);
        return BusiResponse.OK(pageResult);
    }

    @PostMapping("/submitFlow")
    @ApiOperation("委托单提交")
    public BusiResponse submitFlow(@RequestBody @Validated FlowSubmitVO submitVO) {
        String id = submitVO.getId();
        HfEnvEntrustSaveVO hfEnvEntrustSaveVO = hfEnvEntrustService.querySubmitEntrustVO(id);
        hfEnvEntrustSaveVO.setIsSubmit(true);
        hfEnvEntrustSaveVO.setNextUserIdList(submitVO.getNextUserIdList());
        Set<ConstraintViolation<HfEnvEntrustSaveVO>> validate = validator.validate(hfEnvEntrustSaveVO);
        if (!validate.isEmpty()) {
            StringBuilder errBuilder = new StringBuilder();
            for (ConstraintViolation<HfEnvEntrustSaveVO> constraintViolation : validate) {
                String message = constraintViolation.getMessage();
                errBuilder.append(message).append(";");
            }
            return BusiResponse.error(400, errBuilder.toString());
        }
        hfEnvEntrustService.saveEntrust(hfEnvEntrustSaveVO);
        return BusiResponse.OK();
    }

    @PostMapping(value = "/saveEntrust")
    @ApiOperation(value = "委托单功能:新增")
    public BusiResponse saveEntrust(@RequestBody HfEnvEntrustSaveVO hfEnvEntrustSaveVO) {
        Boolean isSubmit = Optional.ofNullable(hfEnvEntrustSaveVO.getIsSubmit()).orElse(false);
        if (isSubmit) {
            Set<ConstraintViolation<HfEnvEntrustSaveVO>> validate = validator.validate(hfEnvEntrustSaveVO);
            if (!validate.isEmpty()) {
                StringBuilder errBuilder = new StringBuilder();
                for (ConstraintViolation<HfEnvEntrustSaveVO> constraintViolation : validate) {
                    String message = constraintViolation.getMessage();
                    errBuilder.append(message).append(";");
                }
                return BusiResponse.error(400, errBuilder.toString());
            }
        }
        HfEnvEntrust hfEnvEntrust = hfEnvEntrustService.saveEntrust(hfEnvEntrustSaveVO);
        return BusiResponse.OK(hfEnvEntrust);
    }

    @GetMapping({"/queryEntrustFlowStartNextNode"})
    @ApiOperation("查看委托流程开始下一节点审批人")
    public BusiResponse queryEntrustFlowStartNextNode(@RequestParam(value = "testPropertyCode", required = false) String testPropertyCode) {
        Map<String, Object> paramData = new HashMap();
        paramData.put("proCode", FlowCodeConsts.ENTRUST_SUBMIT_FLOW);
        Map<String, Object> varsMap = new HashMap<>();
        varsMap.put("testPropertyCode", testPropertyCode);
        paramData.put("vars", JsonUtils.toJson(varsMap));
        BusiRequest request = new BusiRequest();
        request.setData(paramData);
        BusiResponse response = new BusiResponse();
        BeanUtils.copyProperties(FlowApiUtils.listStartNextData(request), response);
        return response;
    }

    @GetMapping("/queryById")
    @ApiOperation(value = "委托单功能:根据id查询数据")
    public BusiResponse queryById(@RequestParam("id") String id) {
        HfEnvEntrustSaveVO byId = hfEnvEntrustService.queryVOById(id);
        return BusiResponse.OK(byId);
    }


    @PostMapping("/delete")
    @ApiOperation(value = "委托单功能:逻辑删除")
    public BusiResponse delete(@RequestBody List<String> idList) {
        hfEnvEntrustService.deleteAndFlowByIds(idList);
        return BusiResponse.ok("删除成功！");
    }

    @PostMapping("/copyById")
    @ApiOperation(value = "委托单功能:复制")
    public BusiResponse copyById(@RequestBody @Validated IdVO idVO) {
        hfEnvEntrustService.copyById(idVO.getId());
        return BusiResponse.ok("复制成功！");
    }

    @Autowired
    private OaTaskClient oaTaskClient;

    @Autowired
    private DebugApiClient debugApiClient;

    @PostMapping("/flowCallback")
    @ApiOperation(value = "工作流:流程回调")
    public BusiResponse flowCallback(HttpServletRequest request, @RequestBody String body) {
        log.info("==================== 流程回调开始 ====================");
        log.info("请求体: {}", body);

        BusiResponseNetty response = new BusiResponseNetty();
        Map<String, Object> param = JsonUtils.toMap(body);
        String callbackType = StringUtils.trimNull(param.get("callbackType"));
        String nodeType = StringUtils.trimNull(param.get("nodeType"));
        String nodeCode = StringUtils.trimNull(param.get("nodeCode"));
        String busiId = StringUtils.trimNull(param.get("busiId"));
        String nextNodeId = StringUtils.trimNull(param.get("nextNodeId"));

        log.info("回调参数解析 - callbackType: {}, nodeType: {}, nodeCode: {}, busiId: {}",
            callbackType, nodeType, nodeCode, busiId);
        System.err.println("param:" + body);

        HfEnvEntrust hfEnvEntrust = hfEnvEntrustService.getById(busiId);
        Assert.notNull(hfEnvEntrust, "数据不存在!");
        String flowId = hfEnvEntrust.getFlowId();
        String entrustCode = hfEnvEntrust.getEntrustCode();
        log.info("委托单信息 - 委托单号: {}, 流程ID: {}", entrustCode, flowId);
        String flowTitle = String.format("试验委托审批:[%s]", entrustCode);
        if (Objects.equals(FlowConst.CALLBACK_PROCESS_REFUSE, callbackType)) {
            // 驳回
            log.info("处理流程驳回 - 委托单号: {}, 更新状态为: {}", entrustCode, EntrustConsts.WTD_STATUS_SHBH);
            UpdateWrapper<HfEnvEntrust> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda()
                .set(HfEnvEntrust::getStatus, EntrustConsts.WTD_STATUS_SHBH)
                .eq(HfEnvEntrust::getId, busiId);
            hfEnvEntrustService.update(updateWrapper);

            debugApiClient.syncEntrustStatus(busiId);
            log.info("流程驳回处理完成 - 委托单号: {}", entrustCode);
        } else if (Objects.equals(FlowConst.CALLBACK_TASK_COMMIT_BEFORE, callbackType)
            && Objects.equals(FlowConst.NODE_DEAL_TYPE_START, nodeType)) {
            log.info("流程启动节点提交前回调 - 委托单号: {}", entrustCode);
        } else if (Objects.equals(FlowConst.CALLBACK_TASK_COMMIT_BEFORE, callbackType)) {
            log.info("任务提交前回调 - 委托单号: {}", entrustCode);
            oaTaskClient.deleteTask(flowId);
            BusiRequest newRequest = new BusiRequest();
            Map<String, Object> flowParams = new HashMap<>();
            flowParams.put("taskId", flowId);
            flowParams.put("nextNodeId", nextNodeId);
            newRequest.setData(flowParams);
            com.hifar.fw.utils.bean.BusiResponse busiResponse = FlowApiUtils.listNextData(newRequest);
            Object resData = busiResponse.getData();
            Map<String, Object> resDataMap = (Map<String, Object>) resData;
            Object nextUserList = resDataMap.get("nextUserList");
            if (Objects.nonNull(nextUserList)) {
                List<Map<String, Object>> nextUserListMapList = (List<Map<String, Object>>) nextUserList;
                for (Map<String, Object> nextUserMap : nextUserListMapList) {
                    String userCode = StringUtils.trimNull(nextUserMap.get("userCode"));
                    oaTaskClient.createTask(flowTitle, flowId, busiId, SystemLoginUser.userCode, userCode);
                }
            }
        } else if (Objects.equals(FlowConst.CALLBACK_PROCESS_END, callbackType)) {
            log.info("流程结束回调 - 委托单号: {}, 开始审批通过处理", entrustCode);
            hfEnvEntrustService.entrustFinish(busiId);
            log.info("委托单审批完成 - 委托单号: {}, 开始完成OA待办任务", entrustCode);
            oaTaskClient.completeTask(flowId);
            log.info("OA待办任务完成 - 委托单号: {}, 流程ID: {}", entrustCode, flowId);
        }

        log.info("==================== 流程回调结束 ====================");
        return BusiResponse.OK();
    }


    @PostMapping("/supplementConditions")
    public BusiResponse supplementConditions(@RequestBody SupplementConditionsVO supplementConditionsVO) {
        hfEnvEntrustService.supplementConditions(supplementConditionsVO);
        return BusiResponse.OK();
    }

    @PostMapping("/saveEntrustFile")
    @ApiOperation("保存委托附件")
    public BusiResponse saveEntrustFile(@RequestBody @Validated HfEnvEntrustSaveFileVO hfEnvEntrustSaveFileVO) {
        hfEnvEntrustService.saveEntrustFile(hfEnvEntrustSaveFileVO);
        return BusiResponse.OK();
    }


    @GetMapping("/queryEntrustFile")
    @ApiOperation("查询委托附件")
    public BusiResponse queryEntrustFile(@RequestParam("id") String id) {
        List<BaseOssFiles> filesList = hfEnvEntrustService.queryEntrustFile(id);
        return BusiResponse.OK(filesList);
    }


    @PostMapping("/exportExcel")
    @ApiOperation(value = "委托单功能:导出数据")
    public Object exportExcel(@RequestBody ExportQueryParamsVO exportQueryParamsVO) {
        QueryParamBean queryParamBean = new QueryParamBean<>(exportQueryParamsVO);
        QueryWrapper<HfEnvEntrust> queryWrapper = queryParamBean.getQueryWrapper();
        BusiResponse export = hfEnvEntrustService.exportExcel(queryWrapper);
        if (export.getCode() == BusiConst.CODE_SUCCESS) {

            String secretLevelText = StringUtils.trimNull(export.getExt("secretLevelText"), "非密");

            String encode = null;
            try {
                encode = URLEncoder.encode(String.format("委托单信息(%s).xlsx", secretLevelText), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/vnd.ms-excel");
            headers.add("Access-Control-Expose-Headers", "Content-Disposition");
            headers.add("Content-Disposition", "filename=" + encode);
            return ResponseEntity.status(HttpStatus.OK).headers(headers).body((byte[]) export.getData());
        }
        return export;
    }


    @ApiOperation("查询委托单号是否存在")
    @GetMapping("/queryExistEntrustCode")
    public BusiResponse queryExistEntrustCode(@RequestParam("entrustCode") String entrustCode) {
        hfEnvEntrustService.lambdaQuery()
                .eq(HfEnvEntrust::getEntrustCode,entrustCode);


        return BusiResponse.OK();
    }


    @ApiOperation("查询委托下试验列表")
    @GetMapping("/testListByEntrust")
    public BusiResponse testListByEntrust(@RequestParam("id") String id) {
//        List<HfEnvEntrustTestVO> testList = testService.testListByEntrust(id);
        List<HfEnvEntrustTaskVO> taskVOList = taskService.listVoByEntrustId(id);
        return BusiResponse.OK(taskVOList);
    }


    @PostMapping("/generateQRCode")
    public BusiResponse generateQRCode(@RequestBody @Validated IdVO idVO) {
        String qrPath = hfEnvEntrustService.generateQrCodeFile2(idVO.getId());
        return BusiResponse.OK(qrPath);
    }

    @GetMapping("/queryEntrustTaskList")
    @ApiOperation("查询委托下项目")
    public BusiResponse queryEntrustTaskList(@RequestParam("id") String entrustId) {
        List<HfEnvReportTaskVO> taskList = hfEnvEntrustService.queryEntrustTaskList(entrustId);
        return BusiResponse.OK(taskList);
    }


    @PostMapping("/generatePackageData")
    public BusiResponse generatePackageData(@RequestBody @Validated IdVO idVO) {
        hfEnvEntrustService.generatePackageData(idVO.getId());
        return BusiResponse.OK();
    }


    @GetMapping("/queryReportFile")
    @ApiOperation("查询委托报告")
    public BusiResponse queryEntrustReport(@RequestParam("id") String id) {
        List<HfEnvReport> reportList = reportService.listByEntrustId(id);
        return BusiResponse.OK(reportList);
    }


    @PostMapping("/batchDownloadReport")
    @ApiOperation("批量下载报告")
    public BusiResponse batchDownloadReport(@RequestBody List<String> idList) {
        List<HfEnvReport> reportList = reportService.listByIds(idList);
        String targetPath = String.format("hifar/report/%s.zip", IdUtils.uuid32());
        String tempDirectoryPath = FileUtils.getTempDirectoryPath() + File.separator + IdUtils.uuid32();
        new File(tempDirectoryPath).mkdirs();
        //要打包的文件
        for (HfEnvReport hfEnvReport : reportList) {
            String reportCode = hfEnvReport.getReportCode();
            String wordPath = hfEnvReport.getWordPath();
            try {
                String wordDownloadPath = tempDirectoryPath + File.separator + reportCode + ".docx";
                MinioUtil.downloadFile(MinioUtil.PRE_DEFAULT, wordPath, wordDownloadPath);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        File zipFile = ZipUtil.zip(tempDirectoryPath);
        try {
            MinioUtils.uploadLocalFileToMinio(MinioUtil.PRE_DEFAULT, targetPath, zipFile.getAbsolutePath(), "application/zip");
            String zipDownloadPath = MinioUtils.getDownloadPath(MinioUtil.PRE_DEFAULT, targetPath, "试验报告.zip");
            return BusiResponse.OK(zipDownloadPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return BusiResponse.error(500, "下载失败!");
    }

    @ApiOperation("作废")
    @PostMapping("/cancel")
    public BusiResponse cancel(@RequestBody @Validated IdVO idVO) {
        hfEnvEntrustService.cancel(idVO.getId());
        return BusiResponse.OK();
    }

    @ApiOperation("校验当日排量")
    @PostMapping("/validateDailyDisplacement")
    public BusiResponse validateDailyDisplacement(@RequestBody @Validated ValidateDailyDisplacementVO validateVO) {
        return hfEnvEntrustService.validateDailyDisplacement(
                validateVO.getEntrustTime(),
                validateVO.getUnitTypeCode(),
                validateVO.getId()
        );
    }

}
